package com.springboot.ww.platform.pd.lms.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.HttpRequest;
import com.google.common.collect.Lists;
import com.springboot.ww.platform.pd.dto.PdStoreTokenVO;
import com.springboot.ww.platform.pd.lms.api.*;
import com.springboot.ww.platform.pd.lms.constant.PdApiConstants;
import com.springboot.ww.platform.pd.lms.dto.*;
import com.springboot.ww.platform.pd.lms.exceptions.NoPermissionException;
import com.springboot.ww.platform.pd.lms.exceptions.TokenNotValidException;
import com.springboot.ww.platform.pd.lms.service.IPdProxy;
import com.springboot.ww.platform.pd.util.SignUtil;
import com.ww.springboot.boot.utils.AssertUtil;
import com.ww.springboot.boot.utils.json.JsonUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.springframework.stereotype.Service;

import java.util.*;

import static com.springboot.ww.platform.pd.lms.constant.PdApiConstants.*;

/**
 * 描述：
 *
 * @author 🧑 ‍wanwei
 * @since 2024-05-13 18:11
 */
@Service
@Slf4j
public class PdProxyImpl implements IPdProxy {

    public final static Map<String, List<String>> warehouseNameMap = new LinkedHashMap() {{
        put("CK0569", Arrays.asList("GC-MD", "GUCANG-MD", "谷仓-美东","GUCANGMEIDONG","美东11号","谷仓11号"));
        put("HWC530630", Arrays.asList("GC-MX", "GUCANG-MX", "谷仓-美西","美西5号","谷仓5号","GUCANGMEIXI"));
        put("USEAST1228", Arrays.asList("ZH-MD", "MEIDONG", "美东", "MD", "EAST"));
        put("USWEST1227", Arrays.asList("ZH-MX", "MEIXI", "美西", "MX", "WEST"));
    }};
    private static final String CN_URL = "https://openapi.kuajingmaihuo.com/openapi/router";

    private static final Map<String, String> SCHEME_MAP = new HashMap() {{
        put("jpg", "data:image/jpg;base64,");
        put("jpeg", "data:image/jpeg;base64,");
        put("png", "data:image/png;base64,");
    }};


    public final static String TOKEN_INVALID_MSG = "access_token is expired";
    public final static String TOKEN_INVALID_MSG_2 = "access_token invalid";

    @Override
    public boolean matchWarehouseCode(String platWarehouseName,String warehouseCode){
        String warehouseCodeMatch = this.getWarehouseCode(platWarehouseName);
        return warehouseCode.equals(warehouseCodeMatch);
    }

    private String getWarehouseCode(String warehouseName){
        warehouseName = warehouseName.toUpperCase();
        for (Map.Entry<String, List<String>> entry : warehouseNameMap.entrySet()) {
            if (entry.getValue().stream().anyMatch(warehouseName::contains)) {
                return entry.getKey();
            }
        }
        return "";
    }

    @Override
    public List<PdListingResp.DataBean> getListingByTime(PdStoreTokenVO storeVO, int page, Date timeStart, Date timeEnd) {
        Map<String, Object> map = new TreeMap<>();
        map.put("pageSize", 20);
        map.put("page", page);
        if (ObjectUtil.isNotEmpty(timeStart)) {
            map.put("createdAtStart", timeStart.getTime() + 1);
            map.put("createdAtEnd", timeEnd.getTime());
        }
        this.cnToken(map, storeVO, PdApiConstants.GET_GOOD_LIST);
        String req = JsonUtil.toJson(map);
        PdListingResp resultBean = postCn(req, PdListingResp.class, "拼多多拉取listing");
        return resultBean.getData();
    }

    private static String postCn(String req) {
        String body = HttpRequest.post(CN_URL).body(req).execute().body();
        log.info("拼多多请求：" + req + " |响应：" + body);
        return body;
    }

    private static <T> T postCn(String req, Class<T> clazz, String title) {
        String body = HttpRequest.post(CN_URL).body(req).execute().body();
        log.info("拼多多请求：" + req + " |响应：" + body);
        PdResult pdResult = JsonUtil.parse(body, PdResult.class);
        if (pdResult == null) {
            throw new RuntimeException(title + " 拼多多接口异常!" + body);
        }
        if (!pdResult.getSuccess()) {
            if(pdResult.getErrorMsg().contains("无权访问") || pdResult.getErrorMsg().contains("access_token don't have this api access")){
                throw new NoPermissionException(title + " 拼多多接口异常!" + pdResult.getErrorMsg());
            }else if(pdResult.getErrorMsg().contains(TOKEN_INVALID_MSG) || pdResult.getErrorMsg().contains(TOKEN_INVALID_MSG_2)){
                throw new TokenNotValidException(title + " 拼多多接口异常!" + pdResult.getErrorMsg());
            }
            throw new RuntimeException(title + " 拼多多接口异常!" + pdResult.getErrorMsg());
        }
        if (pdResult.getResult() == null) {
            return null;
        }
        return JsonUtil.parse(JsonUtil.toJson(pdResult.getResult()), clazz);
    }

    @Override
    public List<PdListingResp.DataBean> getListingBySkcList(PdStoreTokenVO tokenVO, List<String> skcList) {
        Map<String, Object> map = new TreeMap<>();
        map.put("pageSize", 20);
        map.put("page", 1);
        map.put("productSkcIds", skcList);
        this.cnToken(map, tokenVO, PdApiConstants.GET_GOOD_LIST);
        String s = JsonUtil.toJson(map);
        PdListingResp pdListingResp = postCn(s,PdListingResp.class,"拼多多拉取listing");
        return pdListingResp.getData();
    }

    @Override
    public List<PdStockResp.ResultBean.ProductSkuStockListBean> getStockCn(PdStoreTokenVO storeVO, String skcId, PdListingLog listingLog) {
        Map<String, Object> map = new TreeMap<>();
        map.put("productSkcId", skcId);
        cnToken(map, storeVO, PdApiConstants.GET_STOCK_HALF);
        String req = JsonUtil.toJson(map);
        listingLog.setCommonReq(req);
        String body = postCn(req);
        listingLog.setCommonResp(body);
        PdStockResp pdStockResp = JsonUtil.parse(body, PdStockResp.class);
        if (pdStockResp.isSuccess() && ObjectUtil.isNotEmpty(pdStockResp.getResult())) {
            return pdStockResp.getResult().getProductSkuStockList();
        }
        throw new RuntimeException("获取拼多多库存信息失败：" + body);
    }

    @Override
    public void updateStockCn(PdStoreTokenVO storeVO, String productSkcId, List<PdStockEditReq> pdStockEditReqs, PdListingLog listingLog) {
        Map<String, Object> map = new TreeMap<>();
        map.put("productSkcId", productSkcId);
        map.put("quantityChangeMode", "2");
        map.put("skuStockChangeList", pdStockEditReqs);
        cnToken(map, storeVO, PdApiConstants.STOCK_EDIT_HALF);
        String req = JsonUtil.toJson(map);
        listingLog.setCommonReq(req);
        String body = postCn(req);
        listingLog.setCommonResp(body);
        PdStockEditResp pdStockResp = JsonUtil.parse(body, PdStockEditResp.class);
        if (pdStockResp.isSuccess()) {
            return;
        }
        throw new RuntimeException("拼多多调整库存失败：" + body);
    }

    private void cnToken(Map<String, Object> map, PdStoreTokenVO storeVO, String api) {
        map.put("data_type", "JSON");
        map.put("access_token", storeVO.getTokenCn());
        String sign = SignUtil.pd(map, storeVO.getAppKeyCn(), storeVO.getAppSecretCn(), api);
        map.put("sign", sign);
    }

    private void usToken(Map<String, Object> map, PdStoreTokenVO storeVO, String api) {
        map.put("data_type", "JSON");
        map.put("access_token", storeVO.getToken());
        String sign = SignUtil.pd(map, storeVO.getAppKey(), storeVO.getAppSecret(), api);
        map.put("sign", sign);
    }

    /**
     * @param storeVO
     * @param parentCatId
     * @return
     */
    public List<PddCatDTO.ResultDTO.CategoryDTOListDTO> getCatOneLevel(PdStoreTokenVO storeVO, Long parentCatId) {
        Map<String, Object> map = new TreeMap<>();
        map.put("parentCatId", parentCatId);
        this.cnToken(map, storeVO, PdApiConstants.GET_CATS_HALF);
        String s = JsonUtil.toJson(map);
        String body = postCn(s);
        PddCatDTO pddCatDTO = JsonUtil.parse(body, PddCatDTO.class);
        if (pddCatDTO.getSuccess() && ObjectUtil.isNotEmpty(pddCatDTO.getResult())) {
            return pddCatDTO.getResult().getCategoryDTOList();
        }
        throw new RuntimeException("获取拼多多类目失败：" + body);
    }

    @Override
    public PddCatAttrDTO.ResultDTO getCatAttr(PdStoreTokenVO storeVO, Long categoryId) {
        Map<String, Object> map = new TreeMap<>();
        map.put("catId", categoryId);
        cnToken(map, storeVO, PdApiConstants.GET_CATS_ATTRS_HALF);
        String s = JsonUtil.toJson(map);
        String body = postCn(s);
        PddCatAttrDTO pddCatAttrDTO = JsonUtil.parse(body, PddCatAttrDTO.class);
        if (pddCatAttrDTO.getSuccess()) {
            return pddCatAttrDTO.getResult();
        }
        throw new RuntimeException("获取拼多多类目属性失败：" + body);
    }


    public List<PddSpecAttrDTO.ResultDTO.ParentSpecDTOSDTO> parentSpecGet(PdStoreTokenVO storeVO) {
        Map<String, Object> map = new TreeMap<>();
        cnToken(map, storeVO, PdApiConstants.GET_PARENTSPEC_HALF);
        String s = JsonUtil.toJson(map);
        String body = postCn(s);
        PddSpecAttrDTO pddSpecAttrDTO = JsonUtil.parse(body, PddSpecAttrDTO.class);
        if (pddSpecAttrDTO.getSuccess() && ObjectUtil.isNotEmpty(pddSpecAttrDTO.getResult())) {
            return pddSpecAttrDTO.getResult().getParentSpecDTOS();
        }
        throw new RuntimeException("获取拼多多父规格：" + body);
    }


    public List<PdGoodWarehouseDTO.WarehouseDTOListDTO> goodWarehouse(PdStoreTokenVO storeVO, Integer siteId) {
        Map<String, Object> map = new TreeMap<>();
        map.put("siteIdList", Arrays.asList(siteId));
        cnToken(map, storeVO, PdApiConstants.GET_GOOD_WAREHOUSE_HALF);

        PdGoodWarehouseDTO pdGoodWarehouseDTO = postCn(JsonUtil.toJson(map), PdGoodWarehouseDTO.class, "获取拼多多good仓库");
        if (pdGoodWarehouseDTO == null || ObjectUtil.isEmpty(pdGoodWarehouseDTO.getWarehouseDTOList())) {
            return new ArrayList<>();
        }
        return pdGoodWarehouseDTO.getWarehouseDTOList();
    }


    public List<PdFreightTemplateDTO.FreightTemplatesDTO> freightTemplateList(PdStoreTokenVO storeVO) {
        Map<String, Object> map = new TreeMap<>();
        map.put("siteIds", Arrays.asList(100));
        cnToken(map, storeVO, GET_LOGISTICS_TEMPLATE_HALF);
        PdFreightTemplateDTO pdFreightTemplateDTO = postCn(JsonUtil.toJson(map), PdFreightTemplateDTO.class, "获取拼多多运费模板");
        if (pdFreightTemplateDTO == null || ObjectUtil.isEmpty(pdFreightTemplateDTO.getFreightTemplates())) {
            return new ArrayList<>();
        }
        return pdFreightTemplateDTO.getFreightTemplates();
    }

    @Override
    public PddImageDTO uploadImage(PdStoreTokenVO tokenVO, String picUrl) {
        //与前面的sizeMode区分 避免冲突
        return uploadImage(tokenVO, picUrl, null, "3");
    }

    @Override
    public PddImageDTO uploadImage(PdStoreTokenVO tokenVO, String imageUrl, Long catId, String sizeMode) {
        if (ObjectUtil.isEmpty(imageUrl)) {
            return null;
        }
        String suffix = imageUrl.substring(imageUrl.lastIndexOf(".") + 1);
        String scheme = SCHEME_MAP.get(suffix);
        AssertUtil.notNull(scheme, suffix + "图片格式不支持:" + imageUrl);
        Map<String, Object> map = new TreeMap<>();
        //如果是3:4 则使用阿里云自带的裁剪功能处理
        if(sizeMode == "2"){
            imageUrl = imageUrl + "?x-oss-process=image/resize,w_750,h_1000,limit_0,m_pad/crop";
        }else if(sizeMode == "3"){
            //不指定尺寸 则直接裁剪为800*800
            imageUrl = imageUrl + "?x-oss-process=image/resize,w_800,h_800,limit_0,m_pad/crop";
        }
        byte[] bytes;
        try{
            bytes = HttpRequest.get(imageUrl).execute().bodyBytes();
        }catch (Exception e){
            log.error("文件请求失败",e);
            throw new RuntimeException(imageUrl + " 无法访问!");
        }
        map.put("image", scheme + Base64.encodeBase64String(bytes));
        map.put("imageBizType", 0);
        if (ObjectUtil.isNotEmpty(catId)) {
            PdImageOptionsReq pdImageOptionsReq = new PdImageOptionsReq();
            pdImageOptionsReq.setBoost(false);
            pdImageOptionsReq.setCateId(catId);
            pdImageOptionsReq.setSizeMode(sizeMode);
            pdImageOptionsReq.setDoIntelligenceCrop(false);
            map.put("options", pdImageOptionsReq);
        }

        cnToken(map, tokenVO, GET_IMAGE_UPLOAD_HALF);
        PddImageDTO pddImageDTO = this.postCn(JsonUtil.toJson(map), PddImageDTO.class, "拼多多图片上传");
        if (pddImageDTO == null || ObjectUtil.isEmpty(pddImageDTO.getImageUrl())){
            throw new RuntimeException("拼多多图片上传异常：" + JsonUtil.toJson(pddImageDTO));
        }
        if (ObjectUtil.isNotEmpty(catId) && ObjectUtil.isEmpty(pddImageDTO.getUrl())) {
            throw new RuntimeException("拼多多图片上传异常：" + JsonUtil.toJson(pddImageDTO));
        }
        return pddImageDTO;
    }

    /**
     * @param storeVO
     * @param businessId
     * @return
     */
    public String createSizeTemplate(PdStoreTokenVO storeVO, String businessId) {
        Map<String, Object> map = new TreeMap<>();
        map.put("businessId", businessId);
        cnToken(map, storeVO, CREATE_SIZE_CHARTS_TEMPLATE_HALF);
        String s = JsonUtil.toJson(map);
        String body = postCn(s);
        PddSizeChartTemplateDTO pddSizeChartTemplateDTO = JsonUtil.parse(body, PddSizeChartTemplateDTO.class);
        if (pddSizeChartTemplateDTO.getSuccess() && ObjectUtil.isNotEmpty(pddSizeChartTemplateDTO.getResult())) {
            return String.valueOf(pddSizeChartTemplateDTO.getResult().getTempBusinessId());
        }
        throw new RuntimeException("创建临时尺码表异常：" + body);
    }

    /**
     * 创建listing
     *
     * @param pddListingAddDTO
     * @param storeVO
     * @return
     */
    public PdAddListingResp.ResultDTO addListing(PddListingAddReq pddListingAddDTO, PdStoreTokenVO storeVO) {
        cnToken2(pddListingAddDTO, storeVO, GET_GOODS_ADD_HALF);
        //String body = "{\"success\":true,\"result\":{\"productSkuList\":[{\"productSkuId\":\"4983969484\",\"extCode\":\"1\",\"skuSpecList\":[{\"specId1\":16075,\"parentSpecName\":\"颜色\",\"specName1\":\"橙色\",\"parentSpecId\":1001},{\"specId\":12003,\"parentSpecName\":\"尺码\",\"specName\":\"XL\",\"parentSpecId\":3001}],\"productSkcId\":\"6449615341\"},{\"productSkuId\":\"3420494459\",\"extCode\":\"2\",\"skuSpecList\":[{\"specId\":16075,\"parentSpecName\":\"颜色\",\"specName\":\"橙色\",\"parentSpecId\":1001},{\"specId\":8002,\"parentSpecName\":\"尺码\",\"specName\":\"XXL\",\"parentSpecId\":3001}],\"productSkcId\":\"6449615341\"}],\"productId\":\"134324963\",\"productSkcList\":[{\"productSkcId\":\"6449615341\"}]}}";
        String body = postCn(JsonUtil.toJson(pddListingAddDTO));
        PdAddListingResp pdAddListingResp = JsonUtil.parse(body, PdAddListingResp.class);
        if (pdAddListingResp.getSuccess() && ObjectUtil.isNotEmpty(pdAddListingResp.getResult())) {
            return pdAddListingResp.getResult();
        }
        throw new RuntimeException("创建listing失败：" + body);
    }

    private static void cnToken2(PddCommonDTO pddCommonDTO, PdStoreTokenVO storeVO, String api) {
        pddCommonDTO.setAccessToken(storeVO.getTokenCn());
        pddCommonDTO.setDataType("JSON");
        pddCommonDTO.setType(api);
        pddCommonDTO.setAppKey(storeVO.getAppKeyCn());
        pddCommonDTO.setTimestamp(System.currentTimeMillis() / 1000);
        String sign = SignUtil.pd2(pddCommonDTO, storeVO.getAppSecretCn());
        pddCommonDTO.setSign(sign);
    }


    /**
     * 规格创建接口 如果规格值已经存在了 则不会再创建 将直接返回 类目属性中的规格同样适用
     *
     * @param tokenVO
     * @param parentSpecId
     * @param specName
     * @return
     */
    @Override
    public Long specCreate(PdStoreTokenVO tokenVO, Long parentSpecId, String specName) {
        Map<String, Object> map = new TreeMap<>();
        map.put("parentSpecId", parentSpecId);
        map.put("specName", specName);
        cnToken(map, tokenVO, GET_GOODS_SPEC_CREATE_HALF);
        String s = JsonUtil.toJson(map);
        String body = postCn(s);
        PddCreateSonSpecDTO pddCreateSonSpecDTO = JsonUtil.parse(body, PddCreateSonSpecDTO.class);
        if (pddCreateSonSpecDTO.getSuccess() && ObjectUtil.isNotEmpty(pddCreateSonSpecDTO.getResult())) {
            return pddCreateSonSpecDTO.getResult().getSpecId();
        }
        throw new RuntimeException("平台规格属性创建失败：" + body);
    }

    public List<PddSizeChartDTO.ResultDTO.SizeSpecDataListDTO> getSizeChart(PdStoreTokenVO storeVO, Long catId) {
        Map<String, Object> map = new TreeMap<>();
        map.put("catId", catId);
        map.put("pageSize", 50);
        map.put("offset", 0);
        cnToken(map, storeVO, GET_GOODS_SIZE_CHARTS_HALF);
        String s = JsonUtil.toJson(map);
        String body = postCn(s);
        PddSizeChartDTO pddSizeChartDTO = JsonUtil.parse(body, PddSizeChartDTO.class);
        if (pddSizeChartDTO.getSuccess() && ObjectUtil.isNotEmpty(pddSizeChartDTO.getResult())) {
            List<PddSizeChartDTO.ResultDTO.SizeSpecDataListDTO> sizeSpecDataList = pddSizeChartDTO.getResult().getSizeSpecDataList();
            if (ObjectUtil.isEmpty(sizeSpecDataList)) {
                return new ArrayList<>();
            }
            return sizeSpecDataList;
        }
        throw new RuntimeException("拼多多获取尺码表异常：" + body);
    }

    @Override
    public String createSizeChart(PdStoreTokenVO tokenVO, PdCreateChartsDTO pdCreateChartsDTO) {
        pdCreateChartsDTO.setOperatorId(0);
        pdCreateChartsDTO.setOperatorName("0");
        pdCreateChartsDTO.setOperatorType(0);
        pdCreateChartsDTO.setName("临时模板" + System.currentTimeMillis());
        pdCreateChartsDTO.setReusable(false);
        cnToken2(pdCreateChartsDTO, tokenVO, SIZE_CHARTS_CREATE_CHARTS_HALF);
        String body = postCn(JsonUtil.toJson(pdCreateChartsDTO));
        PdCreateChartsResp pdCreateChartsResp = JsonUtil.parse(body, PdCreateChartsResp.class);
        if (pdCreateChartsResp.getSuccess() && ObjectUtil.isNotEmpty(pdCreateChartsResp.getResult())) {
            return pdCreateChartsResp.getResult().getBusinessId();
        }
        throw new RuntimeException("拼多多创建尺码表异常：" + body);
    }

    public String textToImg(PdStoreTokenVO tokenVO, String text) {
        text = text.replace("【", "");
        text = text.replace("】", "");
        Map<String, Object> map = new TreeMap<>();
        map.put("backColor", "#FFFFFF");
        map.put("text", text);
        map.put("align", "left");
        map.put("font", "Source Han Sans CN Heavy");
        map.put("fontColor", "#000000");
        cnToken(map, tokenVO, SIZE_TEXT_TO_PIC_HALF);
        String s = JsonUtil.toJson(map);
        String body = postCn(s);
        PdTextToImgRespDTO pdTextToImgRespDTO = JsonUtil.parse(body, PdTextToImgRespDTO.class);
        if (pdTextToImgRespDTO.getSuccess() && ObjectUtil.isNotEmpty(pdTextToImgRespDTO.getResult())) {
            return pdTextToImgRespDTO.getResult().getImageUrl();
        }
        throw new RuntimeException("平台文字转图片创建失败：[" + text + "] " + body);
    }

    @Override
    public List<PdProductStatusResp.ResultDTO.DataListDTO> getPlatformStatus(PdStoreTokenVO tokenVO, List<String> productSkuIdList) {
        Map<String, Object> map = new TreeMap<>();
        map.put("productSkuIdList", productSkuIdList);
        map.put("pageSize", 100);
        map.put("pageNum", 1);
        cnToken(map, tokenVO, GET_PRODUCT_STATUS_HALF);
        String s = JsonUtil.toJson(map);
        String body = postCn(s);
        PdProductStatusResp pdProductStatusResp = JsonUtil.parse(body, PdProductStatusResp.class);
        if (pdProductStatusResp.getSuccess()) {
            return pdProductStatusResp.getResult().getDataList();
        }

        throw new RuntimeException("平台状态查询失败：" + body);
    }

    @Override
    public List<PdBrandResp.ResultDTO.PageItemsDTO> getBrand(PdStoreTokenVO tokenVO) {
        Map<String, Object> map = new TreeMap<>();
        map.put("pageSize", 100);
        map.put("page", 1);
        cnToken(map, tokenVO, GET_BRAND_HALF);

        String s = JsonUtil.toJson(map);
        String body = postCn(s);
        PdBrandResp pdBrandResp = JsonUtil.parse(body, PdBrandResp.class);
        if (pdBrandResp.getSuccess()) {
            return pdBrandResp.getResult().getPageItems();
        }
        throw new RuntimeException("平台品牌查询失败：" + body);
    }

    @Override
    public Integer getSizeChartsClass(PdStoreTokenVO tokenVO, Long catId) {
        Map<String, Object> map = new TreeMap<>();
        map.put("catId", catId);
        cnToken(map, tokenVO, GET_SIZE_CHARTS_CLASS_HALF);

        String s = JsonUtil.toJson(map);
        String body = HttpRequest.post(CN_URL).body(s).execute().body();
        PdSizeChartsClassResp pdSizeChartsClassResp = JsonUtil.parse(body, PdSizeChartsClassResp.class);
        if (pdSizeChartsClassResp.getSuccess()) {
            return Optional.ofNullable(pdSizeChartsClassResp)
                    .map(PdSizeChartsClassResp::getResult)
                    .map(PdSizeChartsClassResp.ResultDTO::getSizeSpecClassCat)
                    .map(PdSizeChartsClassResp.ResultDTO.SizeSpecClassCatDTO::getClassId)
                    .orElse(null);
        }
        throw new RuntimeException("平台类目尺码分类查询失败：" + body);
    }

    public String uploadFile(PdStoreTokenVO tokenVO, String fileUrl) {
        if (ObjectUtil.isEmpty(fileUrl)) {
            return null;
        }
        Map<String, Object> map = new TreeMap<>();
        byte[] bytes;
        try{
            bytes = HttpRequest.get(fileUrl).execute().bodyBytes();
        }catch (Exception e){
            log.error("文件请求失败",e);
            throw new RuntimeException(fileUrl + " 无法访问!");
        }

        map.put("base64File", Base64.encodeBase64String(bytes));
        cnToken(map, tokenVO, INSTRUCTIONS_UPLOAD_HALF);
        PdUploadResp pdUploadResp = postCn(JsonUtil.toJson(map), PdUploadResp.class, "上传文件");
        if (ObjectUtil.isNotEmpty(pdUploadResp) && ObjectUtil.isNotEmpty(pdUploadResp.getPdfId())) {
            return pdUploadResp.getPdfId();
        }
        throw new RuntimeException("上传文件失败：" + JsonUtil.toJson(pdUploadResp));
    }

    public PdLanguageResp getFileLanguage(PdStoreTokenVO tokenVO, String pdfId) {
        Map<String, Object> map = new TreeMap<>();
        map.put("pdfId", pdfId);
        cnToken(map, tokenVO, GET_INSTRUCTIONS_LANGUAGES);
        return postCn(JsonUtil.toJson(map), PdLanguageResp.class, "识别文件语言");
    }

    public List<PdModelResp.ModelDTO> getModelDTO(PdStoreTokenVO tokenVO, PdModelReq pdModelReq) {
        Map<String, Object> map = new TreeMap<>();
        map.put("pageNo", 1);
        map.put("pageSize", 50);
        map.put("modelType", pdModelReq.getModelType());
        if (ObjectUtil.isNotEmpty(pdModelReq.getModelName())) {
            map.put("modelName", pdModelReq.getModelName());
        }
        if (ObjectUtil.isNotEmpty(pdModelReq.getId())) {
            map.put("id", pdModelReq.getId());
        }
        cnToken(map, tokenVO, GET_MODEL_INFO);

        PdModelResp pdModelResp = postCn(JsonUtil.toJson(map), PdModelResp.class, "拼多多模特信息");
        if (pdModelResp == null || ObjectUtil.isEmpty(pdModelResp.getModelList())) {
            return new ArrayList<>();
        }
        return pdModelResp.getModelList();
    }

    public PdModelResp.ModelDTO getModelById(PdStoreTokenVO tokenVO, String modelId, Integer modelType) {
        PdModelReq pdModelReq = new PdModelReq();
        pdModelReq.setModelType(modelType);
        pdModelReq.setId(modelId);
        List<PdModelResp.ModelDTO> modelDTOList = getModelDTO(tokenVO, pdModelReq);
        if (ObjectUtil.isEmpty(modelDTOList)) {
            throw new RuntimeException(modelId + " 模特不存在");
        }
        return modelDTOList.get(0);
    }

    @Override
    public PdCatModelResp getCatModelById(PdStoreTokenVO tokenVO, Long catId) {
        Map<String, Object> map = new TreeMap<>();
        map.put("catId",catId);
        cnToken(map, tokenVO, GET_CAT_MODEL_INFO);
        PdCatModelResp pdModelResp = postCn(JsonUtil.toJson(map), PdCatModelResp.class, "类目模特信息");
        if(pdModelResp == null){
            return null;
        }
        return pdModelResp;
    }

    @Override
    public List<PdSkuPriceResp.ProductSkuSupplierPriceListDTO> getSkuPriceList(PdStoreTokenVO tokenVO, List<String> skuIdList) {
        List<List<String>> partition = Lists.partition(skuIdList, 50);
        List<PdSkuPriceResp.ProductSkuSupplierPriceListDTO> result = new ArrayList<>();
        partition.forEach(list -> {
            Map<String, Object> map = new TreeMap<>();
            map.put("productSkuIds", list);
            cnToken(map, tokenVO, GET_GOODS_PRICE_LIST_HALF);
            PdSkuPriceResp pdSkuPriceResp = postCn(JsonUtil.toJson(map), PdSkuPriceResp.class, "sku价格获取");
            if (pdSkuPriceResp == null || ObjectUtil.isEmpty(pdSkuPriceResp)) {
                return;
            }
            result.addAll(pdSkuPriceResp.getProductSkuSupplierPriceList());
        });
        return result;
    }
}
